﻿
using ProjBackEnd.Common.Helper;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace ProjBackEnd.Common
{
    public sealed class Function
    {
        public static string GetUUID()
        {
            return DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + System.Guid.NewGuid().ToString("N");
        }


         
        /// <summary>
        /// 根据数据库枚举获取连接字符串
        /// </summary>
        /// <param name="_type"></param>
        /// <returns></returns>
        public static string GetConnectionString(string datasour)
        {
            string constr = "";
            switch (datasour.Trim().ToLower())
            {

                case "tjxt":
                    constr = System.Web.Configuration.WebConfigurationManager.AppSettings["ConnPROJDB"];
                    break;


            }
            return constr;
        }

        /// <summary>
        /// 根据数据库枚举获取连接字符串
        /// </summary>
        /// <param name="_type"></param>
        /// <returns></returns>
        public static string GetConnectionString()
        {
            string constr = "";


            constr = System.Web.Configuration.WebConfigurationManager.AppSettings["ConnPROJDB"];

            return constr;
        }

        /// <summary>
        /// 判断是否为有效的整型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsInteger(string str)
        {
            try
            {
                int i = Convert.ToInt32(str);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 判断是否为有效的Decimal型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsDecimal(string str)
        {
            try
            {
                decimal i = Convert.ToDecimal(str);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool IsDatetime(string str)
        {
            try
            {
                DateTime i = Convert.ToDateTime(str);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取周的第一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime GetWeekFirstDay(DateTime dateTime)
        {
            int weekNo = Convert.ToInt32(dateTime.DayOfWeek);
            weekNo = (weekNo == 0 ? (7 - 1) : (weekNo - 1));
            int daydiff = (-1) * weekNo;
            DateTime day = Convert.ToDateTime(dateTime.AddDays(daydiff).ToString("yyyy-MM-dd"));
            return new DateTime(day.Year, day.Month, day.Day, 0, 0, 0);
        }


        /// <summary>
        /// 获取周的最后一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime GetWeekLastDay(DateTime dateTime)
        {
            int weekNo = Convert.ToInt32(dateTime.DayOfWeek);
            weekNo = (weekNo == 0 ? (7 - 1) : (weekNo - 1));
            int daydiff = (-1) * weekNo;
            DateTime day = Convert.ToDateTime(dateTime.AddDays(daydiff).ToString("yyyy-MM-dd"));
            DateTime lastDay = day.AddDays(6);
            return new DateTime(day.Year, day.Month, day.Day, 0, 0, 0);
        }


        /// <summary>
        /// 返回ASC码的字符
        /// </summary>
        /// <param name="i">ASC码</param>
        /// <returns></returns>
        public static char Chr(int i)
        {
            return Microsoft.VisualBasic.Strings.Chr(i);
        }

        /// <summary>
        /// 获取指定数量的空格
        /// </summary>
        /// <param name="intLen">空格的数量</param>
        /// <returns>字符串</returns>
        public static string Space(int intLen)
        {
            return "".PadRight(intLen, ' ');
        }

        /// <summary>
        /// 字符串右补空格
        /// </summary>
        /// <param name="str"></param>
        /// <param name="intLen"></param>
        /// <returns></returns>
        public static string Space(string str, int intLen)
        {
            return str.Trim().PadRight(intLen, ' ');
        }

        /// <summary>
        /// 字符串右补空格，将全角字符视为两个半角字符
        /// </summary>
        /// <param name="str"></param>
        /// <param name="intLen"></param>
        /// <returns></returns>
        public static string Space2(string str, int intLen)
        {
            foreach (char chr in str)
            {
                if (Convert.ToInt32(chr) > 225)
                    intLen--;
            }

            return Space(str, intLen);
        }

        /// <summary>
        /// 字符串左补空格
        /// </summary>
        /// <param name="str"></param>
        /// <param name="intLen"></param>
        /// <returns></returns>
        public static string SpaceLeft(string str, int intLen)
        {
            return str.Trim().PadLeft(intLen, ' ');
        }

        /// <summary>
        /// 补空格
        /// </summary>
        /// <param name="str"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string FormatString(string str, int length)
        {
            return str.Trim().PadLeft(length, ' ');
        }

        /// <summary>
        /// 按起始位置和长度截取中英文字符混合的字符串
        /// </summary>
        /// <param name="input">字符串</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static string Intercept(string input, int startIndex, int length)
        {
            Encoding encode = Encoding.GetEncoding("gb2312");
            byte[] byteArr = encode.GetBytes(input);
            if (byteArr.Length <= startIndex)
                return input;

            int m = 0, n = 0;
            foreach (byte b in byteArr)
            {
                if (n >= length) break;
                if (b > 127) m++; //重要一步：对前p个字节中的值大于127的字符进行统计
                n++;
            }
            if (m % 2 != 0) n = length + 1; //如果非偶：则说明末尾为双字节字符，截取位数加1

            return encode.GetString(byteArr, startIndex, n);
        }

        /// <summary>
        /// 截取字符串右面部分的指定长度
        /// </summary>
        /// <param name="str">要截取的字符串</param>
        /// <param name="intLen">指定长度</param>
        /// <returns>字符串</returns>
        public static string Right(string str, int intLen)
        {
            string strReturn;
            if (str == null || intLen <= 0)
                return "";
            str = str.PadLeft(intLen, Convert.ToChar(" "));
            strReturn = str.Substring(str.Length - intLen, intLen).Trim();
            return strReturn;
        }

        public static DataTable GetDataTableColumns(DataTable dataTable, string[] strColumns)
        {
            if (dataTable == null)
                return null;

            DataTable tbl = dataTable.Clone();
            tbl.BeginLoadData();
            for (int index = 0; index < dataTable.Rows.Count; index++)
            {
                tbl.ImportRow(dataTable.Rows[index]);
            }

            int i;

            List<string> arr = new List<string>();

            foreach (DataColumn col in tbl.Columns)                         //遍历DataTable的列
            {
                i = 0;
                if (!tbl.Columns.CanRemove(col))                            //如果该列不能移除就继续循环
                    continue;

                foreach (string strColumn in strColumns)                    //遍历传入的列名数组
                {
                    if (col.ColumnName.ToUpper() == strColumn.ToUpper())    //如果DataTable的列和传入的列名相同
                    {
                        i++;
                        break;
                    }
                }
                if (i == 0)                                                 //如果DataTable的列不在出入的列名数组里
                    arr.Add(col.ColumnName);                                //获取要删除的列的列名数组
            }
            for (i = 0; i < arr.Count; i++)                                 //遍历要删除的列的列名数组
            {
                tbl.Columns.Remove(arr[i].ToString());                      //删除该列；
            }
            return tbl;
        }

        /// <summary>
        /// 过滤DataTable返回新DataTable
        /// </summary>
        /// <param name="tbl"></param>
        /// <param name="select"></param>
        /// <param name="sort"></param>
        /// <returns></returns>
        public static DataTable GetDataTableSelect(DataTable tbl, string select, string sort = "")
        {
            DataRow[] array = tbl.Select(select, sort);
            DataTable dataTable = tbl.Clone();
            dataTable.BeginLoadData();
            for (int i = 0; i < array.Length; i++)
            {
                dataTable.ImportRow(array[i]);
            }
            return dataTable;
        }

        /// <summary>
        /// 重新创建DataSet
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="tbls"></param>
        public static void ReBulidDataSet(DataSet ds, List<string> tbls)
        {
            tbls = tbls.Select(s => s.ToUpper()).ToList();
            for (int i = ds.Tables.Count - 1; i >= 0; i--)
            {
                DataTable tbl = ds.Tables[i];
                if (!tbls.Contains(tbl.TableName.ToUpper()))
                {
                    DataRelationCollection relations = ds.Relations;
                    List<DataRelation> relationList = new List<DataRelation>();
                    foreach (DataRelation relation in relations)
                    {
                        if (relation.ChildTable.Equals(tbl) || relation.ParentTable.Equals(tbl))
                        {
                            relationList.Add(relation);
                        }
                    }
                    for (int j = relationList.Count - 1; j >= 0; j--)
                    {
                        ds.Relations.Remove(relationList[j]);
                    }
                    ds.Tables.Remove(tbl.TableName);
                }
            }
        }


        public static void WriteSyslog(string logtp,
            string logremark,
            string inpara,
            string outpara,
            string userid)
        {
            try
            {
                string conn = Function.GetConnectionString( );

                string sql = $@"insert into sys_log(logtp,logremark,logdt,inpara,outpara,userid)
                        values('{logtp}','{logremark}',getdate(),'{inpara}','{outpara}','{userid}')";

                SqlHelper.ExecuteNonQuery(conn, CommandType.Text, sql);
            
            }
            catch
            {

            }
        }

        /// <summary>
        /// 写系统日志
        /// </summary>
        /// <param name="source">日志分类</param>
        /// <param name="message">日志内容</param>
        public static void WriteLog(string source, string message)
        {
            string path = System.Windows.Forms.Application.StartupPath + @"\log\";

            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            //str = str + " 联系单号：" + fkdh;

            //日志文件
            string filename = path + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";

            try
            {
                if (!File.Exists(filename))
                {
                    FileInfo myfile = new FileInfo(filename);
                    FileStream fs = myfile.Create();
                    fs.Close();
                }

                StreamWriter sw = File.AppendText(filename);
                sw.WriteLine(source + ":" + message + " " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                sw.Flush();
                sw.Close();
            }
            catch
            {

            }
        }

        /// <summary>
        /// 写日志文件
        /// </summary>
        /// <param name="str"></param>
        public static void WriteLog(string str)
        {
            string path = System.Web.HttpContext.Current.Server.MapPath("/log");

            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            //日志文件
            string filename = path + @"\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";

            try
            {
                if (!File.Exists(filename))
                {
                    FileInfo myfile = new FileInfo(filename);
                    FileStream fs = myfile.Create();
                    fs.Close();
                }

                StreamWriter sw = File.AppendText(filename);
                sw.WriteLine(str + "  " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                sw.Flush();
                sw.Close();
            }
            catch
            {

            }
        }



        /// <summary>
        /// 将币种转换为符号
        /// </summary>
        /// <param name="currency">币种</param>
        /// <returns>货币符号</returns>
        public static string ConvertCurrencyToSymbol(string currency)
        {
            switch (currency)
            {
                case "RMB":
                    return "¥";
                case "USD":
                    return "$";
                case "HKD":
                    return "HK$";
                case "EUR":
                    return "€";
                case "GBP":
                    return "£";
                default:
                    return "¤";
            }
        }
        /// <summary>
        /// 小写金额转换为大写金额
        /// </summary>
        /// <param name="num">金额</param>
        /// <param name="currency">币种</param>
        /// <returns></returns>
        public static string ConvertChineseCurrency(decimal num, string currency)
        {
            string str1 = "零壹贰叁肆伍陆柒捌玖";            //0-9所对应的汉字 
            string str2 = "万仟佰拾亿仟佰拾万仟佰拾元角分"; //数字位所对应的汉字 
            string str3 = "";    //从原num值中取出的值 
            string str4 = "";    //数字的字符串形式 
            string str5 = "";  //人民币大写金额形式 
            int i;    //循环变量 
            int j;    //num的值乘以100的字符串长度 
            string ch1 = "";    //数字的汉语读法 
            string ch2 = "";    //数字位的汉字读法 
            int nzero = 0;  //用来计算连续的零值是几个 
            int temp;            //从原num值中取出的值 

            num = Math.Round(Math.Abs(num), 2);    //将num取绝对值并四舍五入取2位小数 
            str4 = ((long)(num * 100)).ToString();        //将num乘100并转换成字符串形式 
            j = str4.Length;      //找出最高位 
            if (j > 15) { return "溢出"; }
            str2 = str2.Substring(15 - j);   //取出对应位数的str2的值。如：200.55,j为5所以str2=佰拾元角分 

            //循环取出每一位需要转换的值 
            for (i = 0; i < j; i++)
            {
                str3 = str4.Substring(i, 1);          //取出需转换的某一位的值 
                temp = Convert.ToInt32(str3);      //转换为数字 
                if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15))
                {
                    //当所取位数不为元、万、亿、万亿上的数字时 
                    if (str3 == "0")
                    {
                        ch1 = "";
                        ch2 = "";
                        nzero = nzero + 1;
                    }
                    else
                    {
                        if (str3 != "0" && nzero != 0)
                        {
                            ch1 = "零" + str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                        else
                        {
                            ch1 = str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                    }
                }
                else
                {
                    //该位是万亿，亿，万，元位等关键位 
                    if (str3 != "0" && nzero != 0)
                    {
                        ch1 = "零" + str1.Substring(temp * 1, 1);
                        ch2 = str2.Substring(i, 1);
                        nzero = 0;
                    }
                    else
                    {
                        if (str3 != "0" && nzero == 0)
                        {
                            ch1 = str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                        else
                        {
                            if (str3 == "0" && nzero >= 3)
                            {
                                ch1 = "";
                                ch2 = "";
                                nzero = nzero + 1;
                            }
                            else
                            {
                                if (j >= 11)
                                {
                                    ch1 = "";
                                    nzero = nzero + 1;
                                }
                                else
                                {
                                    ch1 = "";
                                    ch2 = str2.Substring(i, 1);
                                    nzero = nzero + 1;
                                }
                            }
                        }
                    }
                }
                if (i == (j - 11) || i == (j - 3))
                {
                    //如果该位是亿位或元位，则必须写上 
                    ch2 = str2.Substring(i, 1);
                }
                str5 = str5 + ch1 + ch2;

                if (i == j - 1 && str3 == "0")
                {
                    //最后一位（分）为0时，加上“整” 
                    str5 = str5 + '整';
                }
            }
            if (num == 0)
            {
                str5 = "零元整";
            }

            if (currency == "RMB")
            {
                return str5;
            }
            else
            {
                if (str5.Substring(str5.Length - 2) == "角整")
                    return str5.Replace("角整", "拾美分");
                else if (str5.Substring(str5.Length - 3, 1) + str5.Substring(str5.Length - 1) == "零分")
                    return str5.Replace("分", "美分");
                else if (str5.Substring(str5.Length - 3, 1) + str5.Substring(str5.Length - 1) == "角分")
                {
                    str5 = str5.Replace("角", "拾");
                    return str5.Replace("分", "美分");
                }
                else
                {
                    return str5;
                }
            }
        }
        /// <summary>
        /// 财务 数据 前加￥并转换成数组
        /// </summary>
        /// <param name="num"></param>
        /// <param name="currency"></param>
        /// <returns></returns>
        public static string[] ConvertNumberSingle(decimal num)
        {
            num = Math.Round(Math.Abs(num), 2); //将num取绝对值并四舍五入取2位小数 
            string snum = ((long)(num * 100)).ToString();//将num乘100并转换成字符串形式 
            int j = snum.Length;//找出最高位 

            string[] nums = new string[11] { "", "", "", "", "", "", "", "", "", "", "" };
            if (j > 10) { return nums; }

            for (int i = 1; i < j + 1; i++)
            {
                string temp = "";
                string sm = snum;
                temp = sm.Substring(j - i, 1);

                nums[i - 1] = temp;
            }
            nums[j] = "￥";
            return nums;
        }


        /// <summary>
        /// 获取月份的英文简写
        /// </summary>
        /// <param name="month"></param>
        /// <returns></returns>
        public static string GetMonthCode(int month)
        {
            switch (month)
            {
                case 1:
                    return "Jan.";
                case 2:
                    return "Feb.";
                case 3:
                    return "Mar.";
                case 4:
                    return "Apr.";
                case 5:
                    return "May.";
                case 6:
                    return "June.";
                case 7:
                    return "July.";
                case 8:
                    return "Aug.";
                case 9:
                    return "Sept.";
                case 10:
                    return "Oct.";
                case 11:
                    return "Nov.";
                case 12:
                    return "Dec.";
                default:
                    return "";
            }
        }
        /// <summary>
        /// 日期转换为财务格式
        /// </summary>
        /// <param name="dt">日期</param>
        /// <returns>年月日的数组</returns>
        public static string[] ConvetDateToChinese(DateTime dt)
        {
            string[] dates = new string[] { dt.Year.ToString(), dt.Month.ToString(), dt.Day.ToString() };

            for (int i = 0; i < dates.Length; i++)
            {
                string temp = "";
                foreach (char c in dates[i])
                {
                    string s = "";
                    switch (c)
                    {
                        case '0': s = "零"; break;
                        case '1': s = "壹"; break;
                        case '2': s = "贰"; break;
                        case '3': s = "叁"; break;
                        case '4': s = "肆"; break;
                        case '5': s = "伍"; break;
                        case '6': s = "陆"; break;
                        case '7': s = "柒"; break;
                        case '8': s = "捌"; break;
                        default: s = "玖"; break;
                    }
                    temp = temp + s;
                }

                if (dates[i].Length < 4)
                {
                    if (Convert.ToInt32(dates[i]) >= 10)
                    {
                        temp = temp.Substring(0, 1) + "拾" + temp.Substring(1, 1);
                        temp = temp.Replace("零", "");
                    }
                    if (dates[i].Length == 1 || dates[i].EndsWith("0"))
                    {
                        temp = "零" + temp;
                    }

                }
                dates[i] = temp;
            }
            return dates;

        }


        public static byte[] DataSetToByteArr(DataSet ds)
        {
            ds.RemotingFormat = SerializationFormat.Binary;
            MemoryStream ms = new MemoryStream();
            IFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, ds);
            byte[] bArrayResult = ms.ToArray();
            ms.Close();
            return Compress(bArrayResult);
        }

        /// <summary>
        /// 压缩二进制文件
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Compress(byte[] data)
        {
            MemoryStream ms = new MemoryStream();
            Stream zipStream = null;
            zipStream = new GZipStream(ms, CompressionMode.Compress, true);
            //从指定的字节数组中将压缩的字节写入基础流
            zipStream.Write(data, 0, data.Length);
            zipStream.Close();
            ms.Position = 0;
            byte[] compressed_data = new byte[ms.Length];
            ms.Read(compressed_data, 0, int.Parse(ms.Length.ToString()));
            return compressed_data;
        }

        public static byte[] EtractBytesFormStream(Stream zipStream, int dataBlock)
        {
            try
            {
                byte[] data = null;
                int totalBytesRead = 0;
                while (true)
                {
                    Array.Resize(ref data, totalBytesRead + dataBlock + 1);
                    int bytesRead = zipStream.Read(data, totalBytesRead, dataBlock);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    totalBytesRead += bytesRead;
                }
                Array.Resize(ref data, totalBytesRead);
                return data;
            }
            catch
            {
                return null;
            }
        }

        public static byte[] Decompress(byte[] data)
        {
            try
            {
                MemoryStream ms = new MemoryStream(data);
                Stream zipStream = null;
                zipStream = new GZipStream(ms, CompressionMode.Decompress);
                byte[] dc_data = null;
                dc_data = EtractBytesFormStream(zipStream, data.Length);
                return dc_data;
            }
            catch
            {
                return null;
            }
        }
    }
}
